#include "fileSystemHandler.h"
#include "cpuSimulator.h"
#include <QDebug>

/**
 * @brief FileSystemHandler构造函数
 * @param parent 父对象指针
 */
FileSystemHandler::FileSystemHandler(QObject *parent)
    : SystemCallHandler(parent)
    , nextHandleId(1)
    , currentWorkingDirectory(QDir::currentPath())
{
    // 构造函数不需要特殊初始化
}

/**
 * @brief FileSystemHandler析构函数
 */
FileSystemHandler::~FileSystemHandler()
{
    // 关闭所有打开的文件
    for (auto& pair : fileHandles) {
        if (pair.second && pair.second->file) {
            pair.second->file->close();
        }
    }
}

/**
 * @brief 处理中断
 * @param interruptNumber 中断号
 * @param cpu CPU模拟器指针
 * @return SystemCallResult 处理结果
 */
SystemCallResult FileSystemHandler::handleInterrupt(int interruptNumber, CpuSimulator* cpu)
{
    if (!isInterruptSupported(interruptNumber)) {
        return createErrorResult(-1, "不支持的文件系统中断号");
    }
    
    switch (interruptNumber) {
        case 0x10: return handleOpenFile(cpu);
        case 0x11: return handleCloseFile(cpu);
        case 0x12: return handleReadFile(cpu);
        case 0x13: return handleWriteFile(cpu);
        case 0x14: return handleSeekFile(cpu);
        case 0x15: return handleGetFileSize(cpu);
        case 0x16: return handleDeleteFile(cpu);
        case 0x17: return handleRenameFile(cpu);
        case 0x18: return handleFileExists(cpu);
        case 0x19: return handleCreateDirectory(cpu);
        case 0x1A: return handleRemoveDirectory(cpu);
        case 0x1B: return handleGetCurrentDirectory(cpu);
        case 0x1C: return handleSetCurrentDirectory(cpu);
        default:
            return createErrorResult(-1, QString("未实现的文件系统中断: 0x%1").arg(interruptNumber, 2, 16, QChar('0')));
    }
}

/**
 * @brief 获取支持的中断号范围
 * @return QPair<int, int> 中断号范围
 */
QPair<int, int> FileSystemHandler::getSupportedInterruptRange() const
{
    return qMakePair(0x10, 0x1C);
}

/**
 * @brief 获取处理器描述
 * @return QString 描述信息
 */
QString FileSystemHandler::getDescription() const
{
    return "文件系统操作处理器 - 支持文件和目录的创建、读写、删除等操作";
}

/**
 * @brief 重置处理器状态
 */
void FileSystemHandler::reset()
{
    // 关闭所有文件句柄
    for (auto& pair : fileHandles) {
        if (pair.second && pair.second->file) {
            pair.second->file->close();
        }
    }
    
    fileHandles.clear();
    nextHandleId = 1;
    currentWorkingDirectory = QDir::currentPath();
}

/**
 * @brief INT 0x10 - 打开文件
 * @param cpu CPU模拟器指针
 * @return SystemCallResult 处理结果
 */
SystemCallResult FileSystemHandler::handleOpenFile(CpuSimulator* cpu)
{
    int fileNameAddr = cpu->getRegister("AX");
    int accessMode = cpu->getRegister("BX");
    
    QString fileName = readStringFromMemory(cpu, fileNameAddr);
    if (fileName.isEmpty()) {
        return createErrorResult(-1, "无效的文件名地址");
    }
    
    // 分配文件句柄
    int handleId = allocateFileHandle();
    if (handleId == -1) {
        return createErrorResult(-2, "无法分配文件句柄");
    }
    
    // 创建文件句柄对象
    std::unique_ptr<FileHandle> handle(new FileHandle());
    handle->handleId = handleId;
    handle->fileName = fileName;
    handle->accessMode = accessMode;
    handle->position = 0;
    handle->isValid = true;
    
    // 创建QFile对象
    handle->file = std::unique_ptr<QFile>(new QFile(fileName));
    
    // 确定打开模式
    QIODevice::OpenMode openMode;
    switch (accessMode) {
        case 0: // 只读
            openMode = QIODevice::ReadOnly;
            break;
        case 1: // 只写
            openMode = QIODevice::WriteOnly;
            break;
        case 2: // 读写
            openMode = QIODevice::ReadWrite;
            break;
        default:
            openMode = QIODevice::ReadOnly;
            break;
    }
    
    // 打开文件
    if (!handle->file->open(openMode)) {
        return createErrorResult(-3, QString("无法打开文件: %1").arg(fileName));
    }
    
    // 创建文本流
    handle->stream = std::unique_ptr<QTextStream>(new QTextStream(handle->file.get()));
    
    // 存储文件句柄
    fileHandles[handleId] = std::move(handle);
    
    QMap<QString, int> result;
    result["AX"] = handleId;
    
    emit outputMessage(QString("文件已打开: %1 (句柄: %2)").arg(fileName).arg(handleId));
    
    return createSuccessResult(result);
}

/**
 * @brief INT 0x11 - 关闭文件
 * @param cpu CPU模拟器指针
 * @return SystemCallResult 处理结果
 */
SystemCallResult FileSystemHandler::handleCloseFile(CpuSimulator* cpu)
{
    int handleId = cpu->getRegister("AX");
    
    FileHandle* handle = getFileHandle(handleId);
    if (!handle) {
        return createErrorResult(-1, "无效的文件句柄");
    }
    
    // 关闭文件
    if (handle->file) {
        handle->file->close();
    }
    
    // 释放句柄
    deallocateFileHandle(handleId);
    
    QMap<QString, int> result;
    result["AX"] = 0; // 成功
    
    emit outputMessage(QString("文件已关闭 (句柄: %1)").arg(handleId));
    
    return createSuccessResult(result);
}

/**
 * @brief INT 0x12 - 读取文件
 * @param cpu CPU模拟器指针
 * @return SystemCallResult 处理结果
 */
SystemCallResult FileSystemHandler::handleReadFile(CpuSimulator* cpu)
{
    int handleId = cpu->getRegister("AX");
    int bufferAddr = cpu->getRegister("BX");
    int bytesToRead = cpu->getRegister("CX");
    
    FileHandle* handle = getFileHandle(handleId);
    if (!handle || !validateFileAccess(handle, true, false)) {
        return createErrorResult(-1, "无效的文件句柄或权限不足");
    }
    
    if (bytesToRead <= 0 || bytesToRead > MAX_BUFFER_SIZE) {
        return createErrorResult(-2, "无效的读取大小");
    }
    
    // 读取数据
    QByteArray data = handle->file->read(bytesToRead);
    int actualBytesRead = data.size();
    
    // 写入内存
    int bytesWritten = writeDataToMemory(cpu, bufferAddr, data);
    
    QMap<QString, int> result;
    result["AX"] = actualBytesRead;
    
    emit outputMessage(QString("已读取 %1 字节").arg(actualBytesRead));
    
    return createSuccessResult(result);
}

/**
 * @brief INT 0x13 - 写入文件
 * @param cpu CPU模拟器指针
 * @return SystemCallResult 处理结果
 */
SystemCallResult FileSystemHandler::handleWriteFile(CpuSimulator* cpu)
{
    int handleId = cpu->getRegister("AX");
    int bufferAddr = cpu->getRegister("BX");
    int bytesToWrite = cpu->getRegister("CX");
    
    FileHandle* handle = getFileHandle(handleId);
    if (!handle || !validateFileAccess(handle, false, true)) {
        return createErrorResult(-1, "无效的文件句柄或权限不足");
    }
    
    if (bytesToWrite <= 0 || bytesToWrite > MAX_BUFFER_SIZE) {
        return createErrorResult(-2, "无效的写入大小");
    }
    
    // 从内存读取数据
    QByteArray data = readDataFromMemory(cpu, bufferAddr, bytesToWrite);
    
    // 写入文件
    qint64 actualBytesWritten = handle->file->write(data);
    handle->file->flush(); // 确保数据写入磁盘
    
    QMap<QString, int> result;
    result["AX"] = static_cast<int>(actualBytesWritten);
    
    emit outputMessage(QString("已写入 %1 字节").arg(actualBytesWritten));
    
    return createSuccessResult(result);
}

/**
 * @brief INT 0x16 - 删除文件
 * @param cpu CPU模拟器指针
 * @return SystemCallResult 处理结果
 */
SystemCallResult FileSystemHandler::handleDeleteFile(CpuSimulator* cpu)
{
    int fileNameAddr = cpu->getRegister("AX");
    QString fileName = readStringFromMemory(cpu, fileNameAddr);
    
    if (fileName.isEmpty()) {
        return createErrorResult(-1, "无效的文件名");
    }
    
    QFile file(fileName);
    bool success = file.remove();
    
    QMap<QString, int> result;
    result["AX"] = success ? 0 : -1;
    
    if (success) {
        emit outputMessage(QString("文件已删除: %1").arg(fileName));
    } else {
        emit outputMessage(QString("删除文件失败: %1").arg(fileName));
    }
    
    return createSuccessResult(result);
}

// 辅助方法实现

/**
 * @brief 从内存中读取字符串
 * @param cpu CPU模拟器指针
 * @param address 字符串地址
 * @return QString 读取的字符串
 */
QString FileSystemHandler::readStringFromMemory(CpuSimulator* cpu, int address)
{
    QString result;
    int currentAddr = address;
    
    while (currentAddr < address + MAX_FILENAME_LENGTH) {
        int charValue = cpu->getMemory(currentAddr);
        if (charValue == 0) {
            break; // 遇到字符串结束符
        }
        
        result.append(QChar(charValue));
        currentAddr++;
    }
    
    return result;
}

/**
 * @brief 向内存写入字符串
 * @param cpu CPU模拟器指针
 * @param address 目标地址
 * @param str 字符串
 * @return int 写入的字节数
 */
int FileSystemHandler::writeStringToMemory(CpuSimulator* cpu, int address, const QString& str)
{
    int bytesWritten = 0;
    
    for (int i = 0; i < str.length() && i < MAX_FILENAME_LENGTH - 1; ++i) {
        cpu->setMemory(address + i, str.at(i).unicode());
        bytesWritten++;
    }
    
    // 写入字符串结束符
    cpu->setMemory(address + bytesWritten, 0);
    bytesWritten++;
    
    return bytesWritten;
}

/**
 * @brief 从内存读取数据
 * @param cpu CPU模拟器指针
 * @param address 起始地址
 * @param size 数据大小
 * @return QByteArray 读取的数据
 */
QByteArray FileSystemHandler::readDataFromMemory(CpuSimulator* cpu, int address, int size)
{
    QByteArray data;
    data.reserve(size);
    
    for (int i = 0; i < size; ++i) {
        int value = cpu->getMemory(address + i);
        data.append(static_cast<char>(value & 0xFF));
    }
    
    return data;
}

/**
 * @brief 向内存写入数据
 * @param cpu CPU模拟器指针
 * @param address 目标地址
 * @param data 数据
 * @return int 写入的字节数
 */
int FileSystemHandler::writeDataToMemory(CpuSimulator* cpu, int address, const QByteArray& data)
{
    for (int i = 0; i < data.size(); ++i) {
        cpu->setMemory(address + i, static_cast<unsigned char>(data.at(i)));
    }
    
    return data.size();
}

/**
 * @brief 分配文件句柄
 * @return int 新的句柄ID（-1表示失败）
 */
int FileSystemHandler::allocateFileHandle()
{
    if (fileHandles.size() >= MAX_FILE_HANDLES) {
        return -1; // 句柄已满
    }
    
    int handleId = nextHandleId++;
    return handleId;
}

/**
 * @brief 释放文件句柄
 * @param handleId 句柄ID
 */
void FileSystemHandler::deallocateFileHandle(int handleId)
{
    fileHandles.erase(handleId);
}

/**
 * @brief 获取文件句柄
 * @param handleId 句柄ID
 * @return FileHandle* 文件句柄指针
 */
FileHandle* FileSystemHandler::getFileHandle(int handleId)
{
    auto it = fileHandles.find(handleId);
    if (it != fileHandles.end()) {
        return it->second.get();
    }
    return nullptr;
}

/**
 * @brief 验证文件访问权限
 * @param handle 文件句柄
 * @param requireRead 需要读权限
 * @param requireWrite 需要写权限
 * @return bool 权限是否足够
 */
bool FileSystemHandler::validateFileAccess(const FileHandle* handle, bool requireRead, bool requireWrite)
{
    if (!handle || !handle->isValid) {
        return false;
    }
    
    int mode = handle->accessMode;
    
    if (requireRead && mode != 0 && mode != 2) {
        return false; // 需要读权限但没有
    }
    
    if (requireWrite && mode != 1 && mode != 2) {
        return false; // 需要写权限但没有
    }
    
    return true;
}

// 占位实现其他方法
SystemCallResult FileSystemHandler::handleSeekFile(CpuSimulator* cpu) { Q_UNUSED(cpu) return createSuccessResult(); }
SystemCallResult FileSystemHandler::handleGetFileSize(CpuSimulator* cpu) { Q_UNUSED(cpu) return createSuccessResult(); }
SystemCallResult FileSystemHandler::handleRenameFile(CpuSimulator* cpu) { Q_UNUSED(cpu) return createSuccessResult(); }
SystemCallResult FileSystemHandler::handleFileExists(CpuSimulator* cpu) { Q_UNUSED(cpu) return createSuccessResult(); }
SystemCallResult FileSystemHandler::handleCreateDirectory(CpuSimulator* cpu) { Q_UNUSED(cpu) return createSuccessResult(); }
SystemCallResult FileSystemHandler::handleRemoveDirectory(CpuSimulator* cpu) { Q_UNUSED(cpu) return createSuccessResult(); }
SystemCallResult FileSystemHandler::handleGetCurrentDirectory(CpuSimulator* cpu) { Q_UNUSED(cpu) return createSuccessResult(); }
SystemCallResult FileSystemHandler::handleSetCurrentDirectory(CpuSimulator* cpu) { Q_UNUSED(cpu) return createSuccessResult(); } 